#ifndef __COM_HPP__
#define __COM_HPP__

#include <sys/types.h>
#include <sys/ipc.h>
#include<iostream>
#include<cerrno>
#include<string.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include<cassert>
#include<unistd.h>

using namespace std;

#define PATHNAME "."
#define RPOJECTID 0x666

const int shmsize = 4096;

key_t Getkey()
{
    key_t k = ftok(PATHNAME,RPOJECTID);
    if(k == -1)
    {
        cerr<<"errno:"<<errno<<":"<<strerror(errno)<<endl;
        exit(1);
    }
    return k;

}

string ToHex(int k)
{
    char buffer[64] ;
    //cout << buffer << endl;
    snprintf(buffer,sizeof(buffer),"0x%x",k);
    //cout << buffer << endl;
    return buffer;
}

int CreatShmHelp(key_t key,int size,int flag)
{
    int shmid = shmget(key,size,flag);
    if(shmid == -1)
    {
        cerr<<"errno:"<<errno<<":"<<strerror(errno)<<endl;
        exit(2);
    }
    return shmid;

}

int CreatShm(key_t key,int size)
{
    umask(0);
    return CreatShmHelp(key,size,IPC_CREAT | IPC_EXCL | 0666);
}

int GetShm(key_t key,int size)
{
    return CreatShmHelp(key,size,IPC_CREAT);
}

char* AttachShm(int shmid)
{
    char* start = (char*)shmat(shmid,nullptr,0);
    return start;
}

void DetachShm(char* start)
{
    int n = shmdt(start);
    assert(n != -1);
    (void)n;
}

void DelShm(int shmid)
{
    int n = shmctl(shmid,IPC_RMID,nullptr);
    assert(n != -1);
    (void)n;
}

#define SERVER 1
#define CLIENT 0


class Shm{
public:
    Shm(int _type)
    :type(_type)
    {
        key_t key = Getkey();
        if(type == 1)
        {
            shmid = CreatShm(key,shmsize);
            
        }
        else
        {
            shmid = GetShm(key,shmsize);
        }
        start = AttachShm(shmid);
        start[0] = 0;
    }

    char* GetStart(){ return start;};
    ~Shm()
    {
        DetachShm(start);
        if(type == 1)
        {
        DelShm(shmid);
        }
    }

private:
    int type;
    char* start;
    int shmid;
};






#endif